package com.zlc.workflow.core.process.model.design;

import cn.hutool.core.util.ObjectUtil;
import com.zlc.workflow.constant.NodeType;
import com.zlc.workflow.core.process.model.FlowNode;
import com.zlc.workflow.core.process.model.FlowPath;
import com.zlc.workflow.core.process.model.FlowProcess;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class AntDesignUtil {

    public static FlowProcess buildFLowProcess(AntDesignEntity entity) {
        FlowProcess process = new FlowProcess();
        if (!ObjectUtil.isEmpty(entity.getAttr())) {
            process.setProcessCode(entity.getAttr().getProcessCode());
            process.setProcessName(entity.getAttr().getProcessName());
        }
        //节点
        List<FlowNode> flowNodes = buildNodes(entity.getNodeList());
        //路线
        List<FlowPath> flowPaths = buildFlowPath(entity.getLinkList());
        //组装
        buildFlowNodeAndPath(flowNodes, flowPaths);
        process.setNodes(flowNodes);
        return process;
    }


    public static AntDesignEntity buildAntDesignEntity(FlowProcess process,String processId){
        AntDesignEntity entity = new AntDesignEntity();
        entity.setAttr(new AntProcess().setProcessCode(process.getProcessCode()).setProcessName(process.getProcessName()).setId(processId));
        //节点
        List<AntNode> antNodes = flowNodeToAntNodes(process.getNodes());
        //路线
        List<AntLink> antLinks = buildAntLink(process.getNodes());
        //config
        Map<String,Object> configs = new HashMap<>();
        configs.put("showGrid",true);
        configs.put("showGridText","隐藏网格");
        configs.put("showGridIcon","eye");
        entity.setNodeList(antNodes);
        entity.setLinkList(antLinks);
        entity.setConfig(configs);
        return entity;
    }

    private static List<AntLink> buildAntLink(List<FlowNode> flowNodes){
        List<AntLink> antLinks = new ArrayList<>();
        for(FlowNode flowNode : flowNodes){
            List<FlowPath> paths = flowNode.getPaths();
            if(ObjectUtil.isEmpty(paths)){
                continue;
            }
            for(FlowPath path : paths){
                AntLink antLink = new AntLink();
                antLink.setId(path.getNodeId());
                antLink.setSourceId(path.getSource());
                antLink.setTargetId(path.getTarget());
                antLink.setLabel(path.getNodeName() == null || path.getNodeName().equals("null") ? "" : path.getNodeName());
                antLink.setType("link");
                Map<String,Object> cls = new HashMap<>();
                cls.put("linkType","Flowchart");
                cls.put("linkColor","#2a2929");
                cls.put("linkThickness",2);
                antLink.setCls(cls);
                antLink.setColor("black");
                antLinks.add(antLink);
            }
        }
        return antLinks;
    }


    private static List<AntNode> flowNodeToAntNodes(List<FlowNode> flowNodes){
        List<AntNode> antNodes = new ArrayList<>();
        for(FlowNode flowNode : flowNodes){
            AntNode antNode = new AntNode();
            antNode.setId(flowNode.getNodeId())
                    .setNodeName(flowNode.getNodeName())
                    .setNodeNum(flowNode.getNodeNum())
                    .setType(flowNode.getNodeType())
                    .setX((int)flowNode.getX())
                    .setY((int)flowNode.getY())
                    .setColor("#0399F0")
                    .setHeight(flowNode.getHeight())
                    .setWidth(flowNode.getWidth())
                    .setIcon(flowNode.getIcon());
            antNodes.add(antNode);
        }
        return antNodes;
    }

    private static void buildFlowNodeAndPath(List<FlowNode> nodes, List<FlowPath> paths) {
        for (FlowNode node : nodes) {
            String nodeId = node.getNodeId();

            List<FlowPath> nodePaths = paths.stream().filter(path -> path.getSource() != null && path.getSource().equals(nodeId)).collect(Collectors.toList());
            node.setPaths(nodePaths);
        }
    }

    private static List<FlowPath> buildFlowPath(List<AntLink> linkList) {
        List<FlowPath> paths = new ArrayList<>();
        if (ObjectUtil.isEmpty(linkList)) {
            return paths;
        }
        for (AntLink link : linkList) {
            FlowPath path = new FlowPath();
            path.setNodeId(link.getId());
            path.setSource(link.getSourceId());
            path.setTarget(link.getTargetId());
            path.setTo(link.getTargetId());
            path.setNodeType(NodeType.PATH.value());
            path.setNodeName(link.getLabel());
            paths.add(path);
        }
        return paths;
    }

    private static List<FlowNode> buildNodes(List<AntNode> nodeList) {
        List<FlowNode> nodes = new ArrayList<>();
        if (ObjectUtil.isEmpty(nodeList)) {
            return nodes;
        }
        for (AntNode node : nodeList) {
            FlowNode flowNode = new FlowNode();
            flowNode.setNodeId(node.getId());
            flowNode.setNodeNum(node.getNodeNum());
            flowNode.setNodeName(node.getNodeName());
            flowNode.setNodeType(node.getType());
            flowNode.setIcon(node.getIcon());
            flowNode.setX(node.getX());
            flowNode.setY(node.getY());
            flowNode.setHeight(node.getHeight());
            flowNode.setWidth(node.getWidth());
            nodes.add(flowNode);
        }
        return nodes;
    }

}
